package com.qh.paythird.mofang;

import com.qh.pay.api.constenum.YesNoType;
import com.qh.redis.service.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.TreeMap;


public class PaymentUtil {
    private static final Logger logger = LoggerFactory.getLogger(PaymentUtil.class);

    public static String getMerchant_no() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_merchant_no);
    }

    public static String getPartner_id() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_partner_id);
    }

    public static String getApiUrl() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_apiUrl);
    }

    public static String getAlgorithm() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_algorithm);
    }

    public static String getSign_type() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_sign_type);
    }

    public static String getPrivateKey() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_mc_private_key);
    }

    public static String getPublicKey() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_mc_public_key);
    }

    public static String getPtPublicKey() {
        return RedisUtil.getPayCommonValue(MofangProKeyConst.mofang_public_key);
    }

    /**
     * 支付最终请求接口
     *
     * @param requestMap
     * @return
     */
    public static Map<String, Object> sendPost(String service, Map<String, String> requestMap) throws Exception {
        NetUtil netUtil = new NetUtil();
        String randstr = PaymentUtil.createRandom(false, 32);
        requestMap.put("partner_id", getPartner_id());
        requestMap.put("service", service);
        requestMap.put("sign_type", getSign_type());
        requestMap.put("rand_str", randstr);
        requestMap.put("version", "v1");
        requestMap.put("merchant_no", getMerchant_no());
        String data = Tools.getUrlParamsByMap(new TreeMap<>(requestMap))
                .replaceAll("\\\\/", "/").replaceAll("\\\\\\\\", "\\\\");
        String sign = RSAUtils.rsaSign(data, getPrivateKey(), "utf-8", getAlgorithm());
        logger.info("verify====>" + RSAUtils.doCheck(data, sign, getPublicKey(), "utf-8", getAlgorithm()));
        logger.info("签名===>" + sign);
        requestMap.put("sign", sign);
        String responseMsg = netUtil.sendPost(getApiUrl(), 30000, requestMap, "utf-8");
        System.out.println(service + "====>responseMsg====>" + responseMsg);
        Map<String, Object> responseMap = Serialize.parseJsonToMap(responseMsg);
        logger.info("返回数据：" + Serialize.toJosnDate(responseMap));
        if ("0".equals(responseMap.get("errcode").toString())) {
            Map<String, String> responseData = (Map<String, String>) responseMap.get("data");
            String responseParam = Tools.getUrlParamsByMap(new TreeMap<>(responseData));
            Boolean isVerify = RSAUtils.doCheck(responseParam, String.valueOf(responseMap.get("sign")), getPtPublicKey(), "utf-8", getAlgorithm());
            if (isVerify) {
                logger.info("签名验证成功！");
                responseMap.put("isVerify",YesNoType.yes.id());
                return responseMap;
            } else {
                responseMap.put("isVerify",YesNoType.not.id());
                logger.info("签名验证失败！");
                return responseMap;
            }
        } else {
            return responseMap;
        }
    }

    /**
     * 发送下单
     *
     * @param requestMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> sendDirectPayPost(Map<String, String> requestMap) throws Exception {
        return sendPost(MofangConst.DIRECT_PAY_TRADE, requestMap);
    }

    /**
     * 发送下单查询
     *
     * @param requestMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> sendDirectQueryPost(Map<String, String> requestMap) throws Exception {
        return sendPost(MofangConst.OPERATEORDER_VIEW, requestMap);
    }

    /**
     * 发送代付
     *
     * @param requestMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> sendProxyPayPost(Map<String, String> requestMap) throws Exception {
        return sendPost(MofangConst.PROXY_PAY, requestMap);
    }

    /**
     * 发送代付查询
     *
     * @param requestMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> sendProxyQueryPost(Map<String, String> requestMap) throws Exception {
        return sendPost(MofangConst.PROXY_QUERY, requestMap);
    }

    /**
     * 发送可用金额查询
     *
     * @param requestMap
     * @return
     * @throws Exception
     */
    public static Map<String, Object> sendBalanceQueryPost(Map<String, String> requestMap) throws Exception {
        return sendPost(MofangConst.BALANCE_QUERY, requestMap);
    }


    /**
     * 中文数据encode
     *
     * @param gbString
     * @return
     */
    public static String gbEncoding(final String gbString) {   //gbString = "测试"
        char[] utfBytes = gbString.toCharArray();   //utfBytes = [测, 试]  
        String unicodeBytes = "";
        for (int byteIndex = 0; byteIndex < utfBytes.length; byteIndex++) {
            String hexB = Integer.toHexString(utfBytes[byteIndex]);   //转换为16进制整型字符串  
            if (hexB.length() <= 2) {
                hexB = "00" + hexB;
            }
            unicodeBytes = unicodeBytes + "\\u" + hexB;
        }
        System.out.println("unicodeBytes is: " + unicodeBytes);
        return unicodeBytes;
    }

    /**
     * 创建指定数量的随机字符串
     *
     * @param numberFlag 是否是数字
     * @param length
     * @return
     */
    public static String createRandom(boolean numberFlag, int length) {
        String retStr = "";
        String strTable = numberFlag ? "1234567890"
                : "1234567890abcdefghijkmnpqrstuvwxyz";
        int len = strTable.length();
        boolean bDone = true;
        do {
            retStr = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = strTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                retStr += strTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);
        return retStr;
    }
}
